namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;
    using System.Text;
    using System.Xml;
    
    /// <summary>
    /// 1.	Starts at Workplace homepage
    /// 2.	Click on Activities
    /// 3.	Click New button
    /// 4.	Select Appointment and click Ok
    /// 5.	Add random string to subject and description
    /// 6.	Select Required lookup
    /// 7.	Select User from Look for dropdown list
    /// 8.	Select a user and click OK
    /// 9.	Click Save and Close
    /// </summary>

    public class CreateAppointment : CrmWebTest
    {
        public void CreateAppointment_PreWebTest(object sender, PreWebTestEventArgs e)
        {
            EntityRequest er = new EntityRequest();
            er.Type = EntityNames.Users;
            er.ReturnAs = EntityNames.Users;
            er.ParentID = EntityManager.Instance.OrgId;

            System.Collections.Hashtable Props = new System.Collections.Hashtable();

            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                Props.Add("role", e.WebTest.Context["UserRole"]);
            }
            
            EntityRequest AccountEr = new EntityRequest();
            AccountEr.Type = EntityNames.Accounts;
            AccountEr.ParentID = Guid.NewGuid();
            AccountEr.ReturnAs = EntityNames.Accounts;

            Props.Add(EntityNames.Accounts, new EntityRequest[] { AccountEr });

            er.Props = Props;

            System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

            user = (CRMEntity)Entities[EntityNames.Users];
            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);

            orgId = new Guid(user["organizationid"]);
            requiredAttendeesId = new Guid(user["systemuserid"]);
            ownerId = new Guid(user["systemuserid"]);

            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];
            
            user2 = EntityManager.Instance.GetNextUser(new Guid(user["organizationid"]));            
        }
        
        public void CreateAppointment_PostWebTest(object sender, PostWebTestEventArgs e)
        {
            // Don't delete the entity till end of test run as it is deleted from crm.
            EntityManager.Instance.FreeEntity(user);
            EntityManager.Instance.FreeEntity(user2);
         }

        public CreateAppointment()
        {
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());

            gridXml = GridXmlHelper.AppointmentPageViewRefresh(-1, refreshApptView, null);

            this.Proxy = null;            
            PreWebTest += new EventHandler<PreWebTestEventArgs>(CreateAppointment_PreWebTest);
            PostWebTest += new EventHandler<PostWebTestEventArgs>(CreateAppointment_PostWebTest);
        }

        public override IEnumerator<WebTestRequest> GetRequestEnumerator()
        {
            this.BeginTransaction("NavActivityHomepage");

            // Get the home page
            workplace_home_activities_aspx hp = new workplace_home_activities_aspx(user);
            yield return (hp);

            this.EndTransaction("NavActivityHomepage");

            this.BeginTransaction("CreateAppointment");

            activities_dlg_create_aspx createPage = new activities_dlg_create_aspx(user);
            yield return (createPage);

            activities_appointment_edit_aspx editPage = new activities_appointment_edit_aspx(user);
            yield return (editPage);

            referer = editPage.lastResponse.ResponseUri.AbsoluteUri;

            _forms_FormScript_js_aspx formScript = new _forms_FormScript_js_aspx(user);
            formScript.etc = 4201;
            formScript.FormType = "main";
            formScript.FormName = "crmForm";
            headerItem = new WebTestRequestHeader();
            headerItem.Name = "referer";
            headerItem.Value = referer;
            formScript.Headers.Add(headerItem);
            yield return (formScript);

            // Need to Call the DateTime WebService twice as it is required for 
            // start time and end time
            // Call 1
            DateTimeService.DateTimeWebService dtws = new DateTimeService.DateTimeWebService();
            CrmRequest wtr = null;
            string currDate = DateTime.Today.ToString();
            try { dtws.GetFormattedDate(currDate); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);
            }
            yield return (wtr);

            // Call 2
            yield return (wtr);            

            _controls_lookup_lookupmulti_aspx lookup = new _controls_lookup_lookupmulti_aspx(user);
            lookup.Class = "ActivityRecipient";
            lookup.objecttypes = "1,2,4,8,9,10,4000";
            lookup.browse = 0;
            lookup.ShowNewButton = 1;
            lookup.ShowPropButton = 1;
            lookup.DefaultType = 0;
            yield return (lookup);

            _controls_lookup_lookupdata_aspx lookupdata = new _controls_lookup_lookupdata_aspx(user);
            lookupdata.Class = "ActivityRecipient";
            lookupdata.ObjectType = 1;
            lookupdata.objecttypes = "1,2,4,8,9,10,4000";
            lookupdata.browse = 0;
            lookupdata.ShowNewButton = 1;
            lookupdata.ShowPropButton = 1;
            lookupdata.DefaultType = 0;
            lookupdata.Mode = 4;
            lookupdata.ColumnsOnly = 1;
            yield return (lookupdata);

            lookupdata = new _controls_lookup_lookupdata_aspx(user);
            lookupdata.Class = "ActivityRecipient";
            lookupdata.objecttypes = "1,2,4,8,9,10,4000";
            lookupdata.browse = 0;
            lookupdata.ShowNewButton = 1;
            lookupdata.ShowPropButton = 1;
            lookupdata.DefaultType = 0;
            lookupdata.Mode = 4;
            lookupdata.ObjectType = 8;
            lookupdata.searchvalue = null;
            yield return (lookupdata);            

            XmlDocument cont = new XmlDocument();
            cont.LoadXml(EntityXmlHelper.GetCreateAppointmentXml(requiredAttendeesId,8,ownerId,8));
            XmlNode content = cont.SelectSingleNode("appointment");

            ActivitiesWebService.ActivitiesWebService actWs = new ActivitiesWebService.ActivitiesWebService();
            wtr = null;

            try { actWs.Book(content,4201); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0,crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);
            
            AppGridWebService.AppGridWebService ag = new AppGridWebService.AppGridWebService();
            wtr = null;

            try { ag.Refresh(gridXml); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            this.EndTransaction("CreateAppointment");
        }

        private const string newIdMarker = @"SetQueryString(sLocation,""id"",""";
        private string gridXml;
        private CRMEntity user;
        private CRMEntity user2;        
        private string crmServer;
        private string tokenKey;
        private string referer;

        private static string refreshApptView = "00000000-0000-0000-00AA-000010001899";

        private Guid orgId;
        private Guid requiredAttendeesId;
        private Guid ownerId;

        private WRPCInfo rpcInfo;
        private WebTestRequestHeader headerItem;
    }
}